package br.srv.full.virtual.entities.auth;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import javax.persistence.AttributeOverride;
import javax.persistence.AttributeOverrides;
import javax.persistence.Column;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.Table;

import br.srv.full.virtual.bean.base.QueryID;
import br.srv.full.virtual.entities.persons.Client;
import br.srv.full.virtual.entities.persons.Worker;

/**
 * @author Delfino
 * 
 */
@Entity
@Table(name = "users")
@DiscriminatorValue(value = "U")
@Inheritance(strategy = InheritanceType.JOINED)
@NamedQueries( { @NamedQuery(name = "User.FindByEMail", query = "select ul from User ul" + " where ul.email = ?1"),
		@NamedQuery(name = "User.FindByAka", query = "select ul from User ul" + " where ul.aka = ?1"),
		@NamedQuery(name = "User.FindByName", query = "select ul from User ul" + " where ul.name = ?1"),
		@NamedQuery(name = "User.FindByUUID", query = "select ul from User ul where ul.registrationId = ?1") })
@AttributeOverrides( { @AttributeOverride(name = "id", column = @Column(name = "userid")) })
public class User extends Person implements Serializable {

	public static final String FIELD_LOGINS = "logins";
	public static final String FIELD_WORKS = "works";

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	public static final QueryID FindByEMail = new QueryID(User.class, "User.FindByEMail");
	public static final QueryID FindByLogin = new QueryID(User.class, "User.FindByLogin");
	public static final QueryID FindByName = new QueryID(User.class, "User.FindByName");
	public static final QueryID FindByUUID = new QueryID(User.class, "User.FindByUUID");

	/**
	 * Retorna os Logins que este usuário possui no sistema.
	 * 
	 * Um usuário pode ter mais de um login, para que possa usar senhas diferentes para cada conjunto de Role.
	 * 
	 * Uma vez que as informações de login são usadas apenas durante o processo de registro no site, e autoenticação.
	 * já que apos a autorização não é mais solicitada ao banco, apenas mantida em memoria.
	 * 
	 * É melhor e reduz problemas com a necessidade de outro campo vir a ser Eagle.
	 * 
	 * @see Role
	 * @see Login
	 */
	@OneToMany(fetch = FetchType.LAZY, mappedBy = "user", targetEntity = Login.class)
	private List<Login> logins;

	/**
	 * Trabalhos que este usuário atua.
	 * 
	 * sendo usuário uma pessoa, quando extender pessoa deverá permanecer em
	 * user.
	 */
	@OneToMany(fetch = FetchType.LAZY, mappedBy = "user", targetEntity = Worker.class)
	private List<Worker> works;

	/**
	 * @return
	 */
	public List<Login> getLogins() {
		return logins;
	}

	/**
	 * @param logins
	 */
	public void setLogins(List<Login> logins) {
		this.logins = logins;
	}

	/**
	 * @param p_newLogin
	 */
	public void addLogin(Login p_newLogin) {
		if (logins == null) {
			logins = new ArrayList<Login>();
		}
		logins.add(p_newLogin);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
		return getClass().getSimpleName() + " -> " + getName() + ", Apelido: " + getAka() + ", E-Mail: " + getEmail()
				+ ", Id: " + getReduzedId() + ", UUID: " + getRegistrationId();
	}

	/**
	 * @return the works
	 */
	public List<Worker> getWorks() {
		if (works == null) {
			works = new ArrayList<Worker>(1);

		}
		return works;
	}

	/**
	 * @param p_works
	 *            the works to set
	 */
	public void setWorks(List<Worker> p_works) {
		works = p_works;
	}

	/**
	 * @param p_client
	 * @param p_role
	 */
	public void addWork(Client p_client, Role p_role) {
		List<Worker> l_works = getWorks();
		l_works.add(new Worker(this, p_role, p_client));
	}
}